From 456cf011b36de91c9936994b1fa45703adcd309b Mon Sep 17 00:00:00 2001 From: Dawid Rycerz Date: Thu, 3 Jul 2025 10:56:21 +0300 Subject: Initial fork of chrismwilliams/astro-theme-cactus theme --- src/pages/og-image/[...slug].png.ts | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/pages/og-image/[...slug].png.ts (limited to 'src/pages/og-image/[...slug].png.ts') diff --git a/src/pages/og-image/[...slug].png.ts b/src/pages/og-image/[...slug].png.ts new file mode 100644 index 0000000..a4982d8 --- /dev/null +++ b/src/pages/og-image/[...slug].png.ts @@ -0,0 +1,90 @@ +import RobotoMonoBold from "@/assets/roboto-mono-700.ttf"; +import RobotoMono from "@/assets/roboto-mono-regular.ttf"; +import { getAllPosts } from "@/data/post"; +import { siteConfig } from "@/site.config"; +import { getFormattedDate } from "@/utils/date"; +import { Resvg } from "@resvg/resvg-js"; +import type { APIContext, InferGetStaticPropsType } from "astro"; +import satori, { type SatoriOptions } from "satori"; +import { html } from "satori-html"; + +const ogOptions: SatoriOptions = { + // debug: true, + fonts: [ + { + data: Buffer.from(RobotoMono), + name: "Roboto Mono", + style: "normal", + weight: 400, + }, + { + data: Buffer.from(RobotoMonoBold), + name: "Roboto Mono", + style: "normal", + weight: 700, + }, + ], + height: 630, + width: 1200, +}; + +const markup = (title: string, pubDate: string) => + html`
+
+

${pubDate}

+

${title}

+
+
+
+ + + + + + +

${siteConfig.title}

+
+

by ${siteConfig.author}

+
+
`; + +type Props = InferGetStaticPropsType; + +export async function GET(context: APIContext) { + const { pubDate, title } = context.props as Props; + + const postDate = getFormattedDate(pubDate, { + month: "long", + weekday: "long", + }); + const svg = await satori(markup(title, postDate), ogOptions); + const png = new Resvg(svg).render().asPng(); + return new Response(png, { + headers: { + "Cache-Control": "public, max-age=31536000, immutable", + "Content-Type": "image/png", + }, + }); +} + +export async function getStaticPaths() { + const posts = await getAllPosts(); + return posts + .filter(({ data }) => !data.ogImage) + .map((post) => ({ + params: { slug: post.id }, + props: { + pubDate: post.data.updatedDate ?? post.data.publishDate, + title: post.data.title, + }, + })); +} -- cgit v1.2.3